package com.shiguiwu.springmybatis.designpattern.iterator;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @description: 核心类
 * @author: stone
 * @date: Created by 2021/9/7 10:57
 * @version: 1.0.0
 * @pakeage: com.shiguiwu.springmybatis.designpattern.iterator
 */
public class GroupStructure implements Collection<Employee, Link> {

    //组织id,也是头部id
    private String groupId;

    //组织名称
    private String groupName;

    //雇员列表
    private Map<String,Employee> employeeMap = new ConcurrentHashMap<>();

    //组织关系 id-> list
    private Map<String, List<Link>> listMap = new ConcurrentHashMap<>();

    //反向关系链
    private Map<String, String> invertedMap = new ConcurrentHashMap<>();


    public GroupStructure(String groupId, String groupName) {
        this.groupId = groupId;
        this.groupName = groupName;
    }

    @Override
    public boolean add(Employee employee) {
        return null != employeeMap.put(employee.getUserId(), employee);
    }

    @Override
    public boolean remove(Employee employee) {
        return null != employeeMap.remove(employee.getUserId());
    }

    @Override
    public boolean addLink(String key,Link link) {
        invertedMap.put(link.getToId(), link.getFromId());
        if (listMap.containsKey(key)) {
            return listMap.get(key).add(link);
        }
        List<Link> links = new LinkedList<>();
        links.add(link);
        return null != listMap.put(key, links);
    }

    @Override
    public boolean removeLink(String key) {
        return null != listMap.remove(key);
    }

    @Override
    public Iterator<Employee> iterate() {
        return new EmpIterator(this);
    }

    private static class EmpIterator implements Iterator<Employee> {

        private int totalIdx ;

        private String fromId;

        private String toId;

        private Map<String, Integer> keyMap = new HashMap<>();

        private GroupStructure groupStructure;

        public EmpIterator(GroupStructure groupStructure) {
            this.totalIdx = 0;
            this.fromId = groupStructure.groupId;
            this.toId = groupStructure.groupId;
            this.groupStructure = groupStructure;
        }

        @Override
        public boolean hasNext() {
            return totalIdx < groupStructure.employeeMap.size();
        }

        @Override
        public Employee next() {
            List<Link> links = groupStructure.listMap.get(toId);
            int cursorIdx = this.getCursorIdx(toId);
            //同级
            if (null == links) {
                cursorIdx = this.getCursorIdx(fromId);
                links = groupStructure.listMap.get(fromId);
            }

            //上一个节点的扫描
            while (cursorIdx > links.size() - 1) {
                fromId = groupStructure.invertedMap.get(fromId);
                cursorIdx = this.getCursorIdx(fromId);
                links = groupStructure.listMap.get(fromId);
            }
            //获取节点
            Link link = links.get(cursorIdx);
            toId = link.getToId();
            fromId = link.getFromId();
            totalIdx++;
            return groupStructure.employeeMap.get(toId);
        }

        /**
         * 给每个层级定义宽度遍历进度
         * @param key
         * @return 或者内容
         */
        public int getCursorIdx(String key) {
            int idx = 0;
            if (keyMap.containsKey(key)) {
                idx = keyMap.get(key);
                keyMap.put(key, ++idx);
            }
            else {
                keyMap.put(key, idx);
            }
            return idx;
        }
    }

}
